printf("Domain Builder: %s\n", msg);
}
+static int do_kill_domain(int dom_id, int force)
+{
+ char cmd_path[MAX_PATH];
+ dom0_op_t dop;
+ int cmd_fd;
+
+ dop.cmd = DOM0_KILLDOMAIN;
+ dop.u.killdomain.domain = dom_id;
+ dop.u.killdomain.force = force;
+
+ /* open the /proc command interface */
+ sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+ cmd_fd = open(cmd_path, O_WRONLY);
+ if(cmd_fd < 0){
+ perror(PERR_STRING);
+ return -1;
+ }
+
+ write(cmd_fd, &dop, sizeof(dom0_op_t));
+ close(cmd_fd);
+
+ return 0;
+}
+
/* clean up domain's memory allocations */
static void dom_mem_cleanup(dom_mem_t * dom_mem)
{
sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/",
PROC_DOM_DATA);
- while((id_fd = open(dom_id_path, O_RDONLY)) < 0){}
+ while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
read(id_fd, dom_data, sizeof(dom0_newdomain_t));
close(id_fd);
if(argc < 4) {
dberr("Usage: dom_builder <kbytes_mem> <image> <num_vifs> "
"[<initrd=initrd_name>] <boot_params>\n");
- goto out;
+ return -1;
}
/* create new domain and set up all the neccessary mappings */
kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize);
- if(kernel_fd < 0) {
- rc = errno;
- goto out;
- }
+ if(kernel_fd < 0)
+ return -1;
/* request the creation of new domain */
if(!(dom_data = create_new_domain(atol(argv[1]))))
- goto out;
+ return -1;
/* map domain's memory */
if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT-10),
out:
if( rc >= 0 )
- return meminfo->domain;
+ {
+ return meminfo->domain;
+ }
else
- return rc;
+ {
+ if ( dom_data->domain != 0 )
+ do_kill_domain(dom_data->domain, 1);
+ return rc;
+ }
}
{
struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
if ( (ret = final_setup_guestos(p, &op.u.meminfo)) != 0 )
- {
- p->state = TASK_DYING;
- release_task(p);
break;
- }
wake_up(p);
reschedule(p);
ret = p->domain;
static unsigned int pro = 0;
unsigned int dom = get_domnr();
ret = -ENOMEM;
- if ( dom == 0 ) break;
+
+ if ( dom == 0 )
+ break;
+
pro = (pro+1) % smp_num_cpus;
p = do_newdomain(dom, pro);
- if ( p == NULL ) break;
+ if ( p == NULL )
+ break;
ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
- if ( ret != 0 ) break;
+ if ( ret != 0 )
+ {
+ __kill_domain(p);
+ break;
+ }
build_page_list(p);
retval = -ENOMEM;
p = alloc_task_struct();
- if (!p) goto newdomain_out;
+ if ( p == NULL ) return NULL;
memset(p, 0, sizeof(*p));
atomic_set(&p->refcnt, 1);
SET_LINKS(p);
write_unlock_irqrestore(&tasklist_lock, flags);
- newdomain_out:
return(p);
}
+
/* Get a pointer to the specified domain. Consider replacing this
* with a hash lookup later.
*
}
-/* Kill the currently executing domain. */
-void kill_domain(void)
+void __kill_domain(struct task_struct *p)
{
struct list_head *ent;
net_vif_t *vif;
- if ( current->domain == 0 )
+ if ( p->domain == 0 )
{
extern void machine_restart(char *);
printk("Domain 0 killed: rebooting machine!\n");
machine_restart(0);
}
- printk("Killing domain %d\n", current->domain);
+ printk("Killing domain %d\n", p->domain);
- sched_rem_domain(current);
+ sched_rem_domain(p);
- unlink_blkdev_info(current);
+ unlink_blkdev_info(p);
- while ( (ent = current->net_vifs.next) != ¤t->net_vifs )
+ while ( (ent = p->net_vifs.next) != &p->net_vifs )
{
vif = list_entry(ent, net_vif_t, dom_list);
unlink_net_vif(vif);
}
-
- schedule();
- BUG(); /* never get here */
+
+ if ( p == current )
+ {
+ schedule();
+ BUG(); /* never get here */
+ }
+ else
+ {
+ free_task_struct(p);
+ }
+}
+
+
+void kill_domain(void)
+{
+ __kill_domain(current);
}
p = find_domain_by_id(dom);
if ( p == NULL ) return -ESRCH;
- if ( force )
+ if ( p->state == TASK_SUSPENDED )
+ {
+ __kill_domain(p);
+ }
+ else if ( force )
{
cpu_mask = mark_hyp_event(p, _HYP_EVENT_DIE);
hyp_event_notify(cpu_mask);
******************************************************************************/
void sched_add_domain(struct task_struct *p)
{
- p->state = TASK_UNINTERRUPTIBLE;
+ p->state = TASK_SUSPENDED;
p->mcu_advance = 10;
if (p->domain == IDLE_DOMAIN_ID) {
* TASK_UNINTERRUPTIBLE: Domain is blocked but may not be woken up by an
* arbitrary event or timer.
* TASK_WAIT: Domains CPU allocation expired.
- * TASK_STOPPED: not really used in Xen
+ * TASK_SUSPENDED: Domain is in supsended state (eg. start of day)
* TASK_DYING: Domain is about to cross over to the land of the dead.
*/
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_WAIT 4
+#define TASK_SUSPENDED 8
#define TASK_DYING 16
-/* #define TASK_STOPPED 8 not really used */
#define SCHED_YIELD 0x10
struct task_struct *find_domain_by_id(unsigned int dom);
extern void release_task(struct task_struct *);
+extern void __kill_domain(struct task_struct *p);
extern void kill_domain(void);
extern void kill_domain_with_errmsg(const char *err);
extern long kill_other_domain(unsigned int dom, int force);